package com.netty.pro.netty.nianbao_chaibao;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @author xuzn
 * @ClassName: NettyServer
 * @ProjectName netty-pro
 * @date 2020/3/10/10:16
 */
public class MyTcpServer {
  public static void main(String[] args) throws Exception {
    // 创建两个线程组
    /**
     * 1.bossGroup只处理连接请求,真正的业务处理交给workerGroup
     * 2.两个循环都是无限循环
     * 3.bossGroup和workerGroup含有子线程的个数
     * 默认是cpu核数*2
     * 每一个NioEventLoop最终靠EventExecutor进行调用或处理
     */
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    // 创建服务器端启动器
    ServerBootstrap bootstrap = new ServerBootstrap();
    try {
      // 使用链式变成进行设置
      //设置两个线程组
      bootstrap.group(bossGroup, workerGroup)
              // 通道类型是NioServerSocketChannel
              .channel(NioServerSocketChannel.class)
              // 设置线程队列得到连接的个数
              .option(ChannelOption.SO_BACKLOG, 128)
              // 创建一个通道初始化对象
              .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                  ChannelPipeline pipeline = ch.pipeline();
                  pipeline.addLast(new SendMessageDecoder());
                  pipeline.addLast(new SendMessageEncoder());
                  pipeline.addLast(new MyTcpServerHandler());
                }
              });
      System.out.println("服务器准备完成~~~");
      // 绑定一个端口并且同步.生成一个channelFuture对象
      ChannelFuture f = bootstrap.bind(7000).sync();

      // 给f注册监听器
      f.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
          if (future.isSuccess()) {
            System.out.println("监听端口号成功");
          } else {
            System.out.println("监听端口号失败");
          }
        }
      });

      // 对关闭通道进行监听
      f.channel().closeFuture().sync();
    } finally {
      bossGroup.shutdownGracefully();
      workerGroup.shutdownGracefully();
    }
  }
}
